/**
 * Copyright (c) 2006-2007 Jinyi.lu
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of GNU LGPL license by gun.org
 * which accompanies this distribution, and is available at
 * http://gnu.feld-it.at/copyleft/lesser.html
 * 
 * Project Homepage : http://code.google.com/p/demou
 * Source Code: svn checkout http://demou.googlecode.com/svn/trunk/ demou
 * Mailing list : jinyi.lu@gmail.com
 *                stonelu@126.com
 *
 *  
 * Contributors:
 *     JinYi.Lu - initial API and implementation
 */
package cn.tworen.demou.io.flv;

import java.util.HashMap;
import java.util.Map;

import cn.tworen.demou.cmd.DataType;

/**
 * Created on  2007-1-24
 *
 * Title       : MetaData.java
 * Description : 
 * 
 * @author     : LuJinYi
 * @version    : 1.0
 * @Date       : 2007-1-24
 * History     : 
 * 
 */
public class MetaData extends AbsTag implements IMetaData{
	private Map<String, Object> metaDataMap = new HashMap<String, Object>();
	public MetaData() {
		this.type = DataType.STREAM_METADATA;
		this.setMetadataCreator("Demo Record Flv");
		this.setCanSeekToEnd(true);
	}
	public Map<String, Object> getMetaDataMap() {
		return metaDataMap;
	}
	/**
	 * duration: (Number) Length of the FLV in seconds. FLVMDI computes this value.
	 * @param value
	 */
	public void setDuration(int value) {
		this.setMetaDataValue("duration", value);
	}
	/**
	 * width: (Number) Width of the video in pixels. (Flash exporter 1.1 sets this to 0).
	 * height: (Number) Height of the video in pixels. (Flash exporter 1.1 sets this to 0).
	 * @param width
	 * @param height
	 */
	public void setWidthHeight(int width, int height) {
		this.setMetaDataValue("width", width);
		this.setMetaDataValue("height", height);
	}
	/**
	 *  videodatarate: (Number) FLVMDI does not compute this value and imports it if present. (Defaults to 0).
	 *  audiodatarate: (Number) FLVMDI does not compute this value and imports it if present. (Defaults to 0). 
	 * @param videodatarate
	 * @param audiodatarate
	 */
	public void setVideoDataRate(int videodatarate) {
		this.setMetaDataValue("videodatarate", videodatarate);
	}
	public void setAudioDataRate(int audiodatarate) {
		this.setMetaDataValue("audiodatarate", audiodatarate);
	}
	/**
	 * videocodecid: (Number) Video codec ID number used in the FLV. 
	 * 		(Sorenson H.263 =2, Screen Video =3, On2 VP6 = 4 and 5, Screen Video V2 = 6).
	 * audiocodecid: (Number) Audio codec ID number used in the FLV. 
	 * 		(Uncompressed = 0, ADPCM = 1, MP3 = 2, NellyMoser = 5 and 6).
	 * @param videocodecid
	 * @param audiocodecid
	 */
	public void setVideoCodecId(int videocodecid) {
		this.setMetaDataValue("videocodecid", videocodecid);
	}
	public void setAudioCodecId(int audiocodecid) {
		this.setMetaDataValue("audiocodecid", audiocodecid);
	}
	/**
	 * framerate: (Number) FLVMDI computes this value, but uses imported value if not 0.
	 * @param framerate
	 */
	public void setFrameRate(int framerate) {
		this.setMetaDataValue("framerate", framerate);
	}
	/**
	 * audiodelay: (Number) Audio delay in seconds. 
	 * Flash 8 encoder delays the video for better synch with audio (Audio and video does not start both at time 0, 
	 * Video starts a bit later). This value is also important for Flash 8 Video Encoder injected Cue Points, 
	 * because logical time of the cue points does not correspond to physical time they are inserted in the FLV. 
	 * (Cue points are injected before encoding, when the video is shifted by 'audio delay' seconds, 
	 * cue points are also shifted and their physical time in the FLV changes).
	 * @param audiodelay
	 */
	public void setAudioDelay(int audiodelay) {
		this.setMetaDataValue("audiodelay", audiodelay);
	}
	/**
	 * canSeekToEnd: (Boolean) True if the last video tag is a key frame and hence can be 'seek'ed.
	 * @param value
	 */
	public void setCanSeekToEnd(boolean value) {
		this.setMetaDataValue("canSeekToEnd", value);
	}
	/**
	 * lasttimestamp: (Number) TimeStamp of the last tag in the FLV file. 
	 * 
	 * (You may think as 'duration = lasttimestamp + estimated or calculated duration of the last tag'. 
	 * This is not exactly true though; FLVMDI calculates/estimates duration for last Audio and Video tags 
	 * separately and uses the appropriate value for the duration. With version 2.0, FLVMDI is more 
	 * conservative and duration will be equal to lasttimestamp more than 1.x version). 
	 * 
	 * NetStream.Time will not return the duration, or the actual time as one might expect. 
	 * It returns the position of the PlayHead which can only be a timestamp in the FLV file 
	 * (see Position of the PlayHead). So, lasttimestamp value is useful for detecting the end 
	 * of the FLV more than the duration value. 
	 * @param lasttimestamp
	 */
	public void setLastTimestamp(int lasttimestamp) {
		this.setMetaDataValue("lasttimestamp", lasttimestamp);
	}
	/**
	 * creationdate: (String) FLVMDI cannot compute this value and imports it if present. (Defaults to 'unknown').
	 * @param value
	 */
	public void setCreationdate(String value) {
		this.setMetaDataValue("creationdate", value);
	}
	/**
	 * (Number) Filesize in bytes (including the injected data).
	 * @param filesize
	 */
	public void setFileSize(int filesize) {
		this.setMetaDataValue("filesize", filesize);
	}
	/**
	 * (Number) TimeStamp of the last video tag which is a key frame. This info might be
	 * @param lastkeyframetimestamp
	 */
	public void setLastKeyframeTimestamp(int lastkeyframetimestamp) {
		this.setMetaDataValue("lastkeyframetimestamp", lastkeyframetimestamp);
	}
//	/**
//	 * keyframes: (Object) This object is added only if you specify the /k switch. 
//	 * 'keyframes' is known to FLVMDI and if /k switch is not specified, 'keyframes' object will be deleted.
//	 * 'keyframes' object has 2 arrays: 'filepositions' and 'times'. Both arrays have the same number of 
//	 * elements, which is equal to the number of key frames in the FLV. Values in times array are in 'seconds'. 
//	 * Each correspond to the timestamp of the n'th key frame. Values in filepositions array are in 'bytes'. 
//	 * Each correspond to the fileposition of the nth key frame video tag (which starts with byte tag type 9).
//	 * @param keyframes
//	 */
//	public void setKeyFrames(Object keyframes) {
//		this.setMetaDataValue("keyframes", keyframes);
//	}
	/**
	 * videosize: (Number) Total size of video tags in the file in bytes.
	 * @param videosize
	 */
	public void setVideoSize(int videosize) {
		int oldSize = 0;
		if (this.metaDataMap.get("videosize") != null) {
			oldSize = (Integer)this.metaDataMap.get("videosize");
		}
		this.setMetaDataValue("videosize", oldSize + videosize);
	}
	/**
	 * audiosize: (Number) Total size of audio tags in the file in bytes.
	 * @param audiosize
	 */
	public void setAudioSize(int audiosize) {
		int oldSize = 0;
		if (this.metaDataMap.get("audiosize") != null) {
			oldSize = (Integer)this.metaDataMap.get("videosize");
		}
		this.setMetaDataValue("audiosize", oldSize + audiosize);
	}
	/**
	 * metadatacreator: (String) Will be set to 'Manitu Group FLV MetaData Injector 2'.
	 * @param metadatacreator
	 */
	public void setMetadataCreator(String metadatacreator) {
		this.setMetaDataValue("metadatacreator", metadatacreator);
	}
	/**
	 * metadatadate: (Date) Date and time metadata added. (Note that this is not of type string like 'creationdate').
	 * @param metadatadate
	 */
	public void setMetaDataDate(int metadatadate) {
		this.setMetaDataValue("metadatadate", metadatadate);
	}
	/**
	 * (string) Additional string data if specified.
	 * @param xtradata
	 */
	public void setXtradata(int xtradata) {
		this.setMetaDataValue("xtradata", xtradata);
	}
	/**
	 * datasize: (Number) Total size of data tags in the file in bytes.
	 */
	public void setMetaDataSize(int datasize) {
		this.setMetaDataValue("datasize", datasize);
	}
	public void setMetaDataValue(String name, Object value) {
		this.metaDataMap.put(name, value);
	}
}
